#include <iostream>
#include <vector>
#include <thread>
#include <chrono>
#include <cassert>

#include "../../include/memPool/pool.hpp"

// 单线程基本功能测试
void testBasicFunctionality() {
    std::cout << "=== 测试基本功能 ===" << std::endl;
    
    // 使用单例模式获取内存池实例
    auto memPool = wheels::memPool<int>::create_shared();
    
    // 注册内存类型
    memPool->registerType(10, 5); // 注册大小为10，初始池大小为5的内存块
    
    // 测试内存分配
    std::vector<std::shared_ptr<int>> allocations;
    for (int i = 0; i < 10; ++i) {
        auto ptr = memPool->malloc(10);
        assert(ptr != nullptr);
        allocations.push_back(ptr);
        
        // 写入测试数据
        ptr.get()[0] = i;
    }
    
    // 验证写入的数据
    for (int i = 0; i < 10; ++i) {
        auto ptr = allocations[i];
        assert(ptr.get()[0] == i);
    }
    
    // 测试内存释放
    for (int i = 0; i < 5; ++i) {
        memPool->free(10, allocations.back());
        allocations.pop_back();
    }
    
    // 再次分配应该重用已释放的内存
    for (int i = 0; i < 5; ++i) {
        auto ptr = memPool->malloc(10);
        assert(ptr != nullptr);
    }
    
    std::cout << "基本功能测试通过" << std::endl;
}

// 多线程并发测试
void testMultiThreading() {
    std::cout << "=== 测试多线程并发 ===" << std::endl;
    
    auto memPool = wheels::memPool<double>::create_shared();
    memPool->registerType(20, 100); // 注册大小为20，初始池大小为100的double内存块
    
    const int THREAD_COUNT = 8;
    const int ALLOCATIONS_PER_THREAD = 100;
    
    std::vector<std::thread> threads;
    
    for (int t = 0; t < THREAD_COUNT; ++t) {
        threads.emplace_back([&memPool, t]() {
            std::vector<std::shared_ptr<double>> thread_allocations;
            
            // 分配内存
            for (int i = 0; i < ALLOCATIONS_PER_THREAD; ++i) {
                auto ptr = memPool->malloc(20);
                if (ptr) {
                    // 写入线程标识和索引
                    ptr.get()[0] = t;
                    ptr.get()[1] = i;
                    thread_allocations.push_back(ptr);
                }
            }
            
            // 随机延迟，增加竞态条件可能性
            std::this_thread::sleep_for(std::chrono::milliseconds(rand() % 50));
            
            // 释放一半内存
            size_t half = thread_allocations.size() / 2;
            for (size_t i = 0; i < half; ++i) {
                memPool->free(20, thread_allocations.back());
                thread_allocations.pop_back();
            }
            
            // 再次分配
            for (int i = 0; i < 50; ++i) {
                auto ptr = memPool->malloc(20);
                if (ptr) {
                    thread_allocations.push_back(ptr);
                }
            }
        });
    }
    
    // 等待所有线程完成
    for (auto& thread : threads) {
        thread.join();
    }
    
    std::cout << "多线程并发测试通过" << std::endl;
}

// 测试自动扩容和最佳匹配
void testAutoResizeAndBestFit() {
    std::cout << "=== 测试自动扩容和最佳匹配 ===" << std::endl;
    
    auto memPool = wheels::memPool<char>::create_shared();
    
    // 注册几个不同大小的内存块
    memPool->registerType(8, 10);  // 8字节
    memPool->registerType(16, 10); // 16字节
    memPool->registerType(32, 10); // 32字节
    
    // 测试请求不存在的大小，应该返回最佳匹配
    auto ptr1 = memPool->malloc(12); // 应该匹配16字节
    auto ptr2 = memPool->malloc(24); // 应该匹配32字节
    
    assert(ptr1 != nullptr);
    assert(ptr2 != nullptr);
    
    // 测试自动扩容
    std::vector<std::shared_ptr<char>> large_allocations;
    for (int i = 0; i < 50; ++i) { // 超出初始大小
        auto ptr = memPool->malloc(8);
        assert(ptr != nullptr);
        large_allocations.push_back(ptr);
    }
    
    // 释放内存
    for (auto& ptr : large_allocations) {
        memPool->free(8, ptr);
    }
    memPool->free(16, ptr1);
    memPool->free(32, ptr2);
    
    std::cout << "自动扩容和最佳匹配测试通过" << std::endl;
}

// 测试异常处理
void testExceptionHandling() {
    std::cout << "=== 测试异常处理 ===" << std::endl;
    
    auto memPool = wheels::memPool<long long>::create_shared();
    
    // 测试释放空指针
    bool result = memPool->free(10, std::shared_ptr<long long>());
    assert(!result);
    
    // 测试释放到未注册的内存池
    memPool->registerType(10, 5);
    auto ptr = memPool->malloc(10);
    result = memPool->free(20, ptr); // 错误的大小
    assert(!result);
    
    // 正确释放
    result = memPool->free(10, ptr);
    assert(result);
    
    std::cout << "异常处理测试通过" << std::endl;
}

int main() {
    std::cout << "开始memPool模块测试..." << std::endl;
    
    try {
        testBasicFunctionality();
        testMultiThreading();
        testAutoResizeAndBestFit();
        testExceptionHandling();
        
        std::cout << "\n所有测试通过！" << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "测试失败: " << e.what() << std::endl;
        return 1;
    } catch (...) {
        std::cerr << "测试失败: 未知异常" << std::endl;
        return 1;
    }
    
    return 0;
}